% TEST_ID: LANG-EXPAND-0067
% CATEGORY: language/convert
% 测试 struct2cell

function test_struct2cell
    S = struct();
    S.x = linspace(0, 2 * pi, 10);
    S.y = sin(S.x);
    S.title = 'y = sin(x)';
    C = struct2cell(S);
    result = [
        {[0 0.698131700797732 1.396263401595464 2.094395102393195 2.792526803190927 3.490658503988659 4.188790204786391 4.886921905584122 5.585053606381854 6.283185307179586]}
        {[0 0.642787609686539 0.984807753012208 0.866025403784439 0.342020143325669 -0.342020143325669 -0.866025403784438 -0.984807753012208 -0.642787609686540 -0.000000000000000]}
        {'y = sin(x)'}
    ];


    assert_isequal_tol(C, result)


    names = {'Alice', 'Bob';'Charlie', 'David'};
    ages = 20;
    occupations = {'Engineer', 'Doctor';'Artist', 'Teacher'};

    S = struct('name', names, 'age', ages, 'occupation', occupations);
    C = struct2cell(S);
    result = cell(3, 2, 2);
    result(:, :, 1) = [
        {'Alice'} {'Charlie'}
        {[20]} {[20]}
        {'Engineer'} {'Artist'}];


    result(:, :, 2) = [
        {'Bob'} {'David'}
        {[20]} {[20]}
        {'Doctor'} {'Teacher'}];


    ages = {25, 30;20, 25};
    S = struct('name', names, 'age', ages, 'occupation', occupations);
    C = struct2cell(S);
    result = cell(3, 2, 2);
    result(:, :, 1) = [
        {'Alice'} {'Charlie'}
        {[25]} {[20]}
        {'Engineer'} {'Artist'}];


    result(:, :, 2) = [
        {'Bob'} {'David'}
        {[30]} {[25]}
        {'Doctor'} {'Teacher'}];

    assert_isequal_tol(C, result);

    % 创建结构体
    s = struct();

    % 为字段赋值
    s.name = 'a';
    s.size = [1 1];
    s.bytes = 16;
    s.class = 'double';
    s.("global") = 0;
    s.sparse = 0;
    s.complex = 1; % 创建一个空的结构体作为嵌套字段
    s.("persistent") = 0;

    s2(1) = s;

    s = struct();
    s.name = 'b';
    s.size = [1 1];
    s.bytes = 4;
    s.class = 'single';
    s.("global") = 0;
    s.sparse = 0;
    s.complex = 0;
    s.("persistent") = 0;

    s2(2) = s;

    C = struct2cell(s2)
end


function assert_isequal_tol(x, y)
    for i = 1:numel(y)
        assert_istrue(x{i}, y{i})
    end
end

function assert_istrue(x, y)
    assert(isequal(x, y) | all(abs(x - y) < 1e-12, 'all'));
end

function assert_isequal(x, y)
    assert(isequal(x, y));
end